/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sourceryobjects;

import java.io.Serializable;
import sourcery.GraphicsContext;

/**
 *
 * @author claire
 */
public class sRelation  implements Serializable {

//    public sRelation(sPoint point, double strength) {
//        this.coords = point;
//        this.strength = strength;
//        if (types == null) {
//            types = new ArrayList<sRelationType>();
//        }
//    }
    public sRelation(sNode a, sNode b, sRelationType type) {
        this.a = a;
        this.b = b;
        this.type = type;
    }

    private sNode a;
    private sNode b;
    private sRelationType type;
    private String name;

    
    public void setName(String name) { this.name = name; }
    public String getName() { return name; }
    //public static ArrayList<sRelationType> types;

    public sNode getA() {
        return a;
    }
    public sNode getB() {
        return b;
    }
    public void connectTo(sNode b) {
        this.b=b;
    }
    public void connectFrom(sNode a) {
        this.a=a;
    }

//    public sPoint getCoords() {
//        return coords;
//    }

    public void update() {
        sPoint apull, bpull;
        sPoint vectorab = b.getCoords().minus(a.getCoords()); // A vector from A to B
        sPoint normalab = vectorab.normal();
        double distanceab = vectorab.length();

        if(distanceab < type.getMinLength()) {
            apull = normalab.scale(distanceab - type.getMinLength());
            bpull = normalab.scale(type.getMinLength() - distanceab);
        } else if(distanceab > type.getMaxLength()) {
            apull = normalab.scale(distanceab - type.getMaxLength());
            bpull = normalab.scale(type.getMaxLength() - distanceab);
        } else {
            apull = new sPoint(0,0);
            bpull = new sPoint(0,0);
        }

        if(type.getMaxAngle() - type.getMinAngle() < 360){
            double anglerange = modulo((type.getMaxAngle() - type.getMinAngle()), 360);
            double angledir = modulo(vectorab.getAngleD(), 360);
            double anglefromstart = modulo(angledir - type.getMinAngle(), 360);
            //double anglefromend = modulo(angledir - type.getMaxAngle(), 360);
            double anglechoice = 0;
            if(anglefromstart > anglerange) {
                sPoint reAngledVector;
                if(anglefromstart > anglerange / 2 + 180) { // if it's closer to the start angle
                    anglechoice = Math.toRadians(type.getMinAngle());
                } else { // if it's closer to the end angle
                    anglechoice = Math.toRadians(type.getMaxAngle());
                }
                reAngledVector = new sPoint(
                    Math.cos(anglechoice),
                    Math.sin(anglechoice)
                    ).scale(distanceab);
                apull.add(vectorab.minus(reAngledVector));
                bpull.add(vectorab.minus(reAngledVector));
            }
        }

        a.pull(apull.scale(type.getStrengthA()));
        b.pull(bpull.scale(-type.getStrengthB()));


    }
    public double modulo (double numerator, double modulo) {
        return numerator - (Math.floor(numerator / modulo)*modulo);
    }
    public void draw(GraphicsContext gc) {
        type.draw(gc, a, b);
    }
}
